home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume2
/
graphics
/
surf_1.of
< prev
next >
Wrap
Text File
|
1988-10-21
|
66KB
|
2,926 lines
Path: xanth!mcnc!rutgers!mailrus!ames!ll-xn!adelie!infinet!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v02i002: surf - produce bezier surfaces of revolution, Part01/03
Message-ID: <9732@swan.ulowell.edu>
Date: 20 Oct 88 01:31:30 GMT
Organization: University of Lowell, Computer Science Dept.
Lines: 2915
Approved: page@swan.ulowell.edu
Submitted-by: edavies@uvvm.bitnet (Eric Davies)
Posting-number: Volume 2, Issue 2
Archive-name: graphics/surf.1of3
Surf is a program for producing bezier surfaces of revolution. It
produces awesome pictures of wine glasses and doorknobs, and other
objects one could turn on a lathe. Surf includes the capacity to map
iff image files onto any surface that it can draw.
# This is a shell archive. Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
# ./menudef.c
# ./menudef.h
# ./menuexp.h
# ./mergergb.c
# ./mergergb.lnk
# ./mouse.c
# ./mytypes.h
# ./packer.c
# ./poly.c
# ./poly.h
# ./readilbm.c
# ./readilbm.h
# ./revolve.c
# ./revolve.h
# ./scrndef.c
# ./scrndef.h
# ./scrnio.c
# ./scrnio.h
# ./scrnio.ih
# ./scrnops.c
# ./surf.lnk
# ./writeilbm.c
#
if `test ! -s ./menudef.c`
then
echo "writing ./menudef.c"
cat > ./menudef.c << '\Rogue\Monster\'
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#ifdef MANX
#include <functions.h>
#endif
#include "scrnio.h"
#include "menudef.h"
#include "scrndef.h"
#include "poly.h"
#include "readilbm.h"
#define Selected(ax) ((ax).Flags & CHECKED)
#include "menu_color.c"
#include "menu_scrn.c"
#include "menu_image.c"
#include "menu_files.c"
struct Menu menu[] ={
{ &menu[1], /* next menu */
8, 0, /* x, y */
6*8, 10, /* w,h */
MENUENABLED,
(BYTE *)"File",
fileitems,
0,0,0,0
},
{ &menu[2], /* next menu */
7*8, 0, /* x, y */
6*8, 10, /* w,h */
MENUENABLED,
(BYTE *)"Color",
coloritems,
0,0,0,0
},
{ &menu[3], /* next menu */
14*8,0, /* x, y */
7*8, 10, /* w,h */
MENUENABLED,
(BYTE *)"Screen",
scrnitems,
0,0,0,0
},
{ NULL, /* next menu */
22*8,0, /* x, y */
6*8, 10, /* w,h */
MENUENABLED,
(BYTE *)"Image",
imageitems,
0,0,0,0
}
};
void MenuHandler(code)
USHORT code;
{
if( code == 0xffff ) { /* invalid menu pick */
return;
}
switch( MENUNUM(code)) {
case 0: /* write ilbm */
MenuDoFile(ITEMNUM(code));
break;
case 1: /* set screen color */
MenuSetColMap();
break;
case 2: /* set screen type */
MenuSetScrn();
break;
case 3: /* set image stuff */
MenuSetImage();
break;
default:
break;
}
}
\Rogue\Monster\
else
echo "will not over write ./menudef.c"
fi
if `test ! -s ./menudef.h`
then
echo "writing ./menudef.h"
cat > ./menudef.h << '\Rogue\Monster\'
extern struct Menu menu[];
extern void MenuHandler(/* USHORT */);
\Rogue\Monster\
else
echo "will not over write ./menudef.h"
fi
if `test ! -s ./menuexp.h`
then
echo "writing ./menuexp.h"
cat > ./menuexp.h << '\Rogue\Monster\'
#ifndef MENUEXP_H_FILE
#define MENUEXP_H_FILE
#ifndef INTUITION_INTUITION_H
#include <intuition/intuition.h>
#endif INTUITION_INTUITION_H
extern USHORT *AbortDrawPtr;
extern USHORT *DebugOnPtr;
#define AbortDraw (*AbortDrawPtr & CHECKED)
#define ClrAbort() { *AbortDrawPtr &= ~CHECKED; }
#define DebugOn (*DebugOnPtr & CHECKED)
#endif MENUEXP_H_FILE
\Rogue\Monster\
else
echo "will not over write ./menuexp.h"
fi
if `test ! -s ./mergergb.c`
then
echo "writing ./mergergb.c"
cat > ./mergergb.c << '\Rogue\Monster\'
/*
* This program, when called with arg "smith", tries to read smith.r, smith.g
* and smith.b, and write a combined raw data file acceptable to RAY2, called
* smith.tmp
*/
#include <stdio.h>
#include "mytypes.h"
#define RED 0
#define GRN 1
#define BLU 2
#define NumPrims 3 /* number of primary colors */
#define MakeID(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) )
#define ID_FORM MakeID('F','O','R','M')
#define ID_ILBM MakeID('I','L','B','M')
#define ID_BMHD MakeID('B','M','H','D')
#define ID_CMAP MakeID('C','M','A','P')
#define ID_CAMG MakeID('C','A','M','G')
#define ID_BODY MakeID('B','O','D','Y')
#define ROUNDUP(x) ( ((x)+1) & (~1L) )
struct CHUNK {
unsigned long Id, Size;
} Chunk;
struct BMHD {
short w,h,x,y;
char npl,mask,compress,pad1;
short transparentColor;
char xAspect,yAspect;
short pageWidth,pageHeight;
};
/*
* compare width and height of two bit maps
* return false if equal
*/
bool CmpBMHD(a, b)
struct BMHD *a, *b;
{
return( a->w != b->w ||
a->h != b->h ||
a->npl != b->npl
);
}
struct BMHD bmhd[NumPrims];
static FILE *ftrip[NumPrims], *fout;
char *nametrip[NumPrims];
char *oname;
bool FileError;
short depth;
unsigned char colmap[NumPrims][32][3];
/*
* read len bytes from selected file
*/
void FRead(buffer, len, filenum)
char *buffer;
int len, filenum;
{
if( fread(buffer, len, 1, ftrip[filenum]) == 0 ) {
fprintf(stderr, "read error in %s\n", nametrip[filenum] );
exit(-1);
}
}
#define ABORT(str) { fprintf(stderr,str); exit(-1); }
#define ReadChunk() FRead(&Chunk, sizeof(Chunk), filenum)
void ReadIffHeaders(filenum)
int filenum;
{
long ILBMid;
bool cmapFlag = false,
bmhdFlag = false;
short i;
ReadChunk ();
if (Chunk.Id != ID_FORM)
ABORT ("Not an IFF File");
FRead (&ILBMid, 4, filenum);
if (ILBMid != ID_ILBM)
ABORT ("Not an ILBM File");
while (1) {
long camgdata;
ReadChunk ();
if (Chunk.Id == ID_BODY) {
if (!cmapFlag) {
printf("no cmap before body in %s\n", nametrip[filenum]);
FileError = true;
}
if (!bmhdFlag) {
printf("no bmhd before the body in %s\n", nametrip[filenum]);
FileError = true;
}
return;
}
if( feof( ftrip[filenum] ) ) {
printf("reached end of file without seeing body in %s\n", nametrip[filenum]);
FileError = true;
return;
}
switch (Chunk.Id) {
case ID_CMAP:
FRead (colmap[filenum], Chunk.Size, filenum);
for (i = 0; i < 32; i++) {
colmap[filenum][i][filenum] >>= 4;
}
cmapFlag = true;
break;
case ID_BMHD:
FRead(&bmhd[filenum], Chunk.Size, filenum);
bmhdFlag = true;
break;
case ID_CAMG:
FRead( &camgdata, sizeof(camgdata),filenum );
break;
default: /* unknown identifier */
fseek( ftrip[filenum], Chunk.Size, 1);
break;
}
}
}
/*
* leftmost pixel of byte is in most significant bit of byte
*/
static char GetIlbmVal( rastlist, h)
char *rastlist[6];
int h;
{
int i;
char value = 0;
short mask, bytep;
mask = 0x80 >> ( h & 7);
bytep = h >> 3;
for( i = depth-1; i >= 0; i-- ) {
value <<= 1;
value |= (*(rastlist[i]+bytep) & mask) ? 1: 0;
}
return( value );
}
/*
* decompress a runlength row of bytes
*/
static void ReadDecomLine(linebytes, rp, filenum)
int linebytes, filenum;
char *rp;
{
int runlen;
char pixel;
while (linebytes) {
runlen = getc (ftrip[filenum]);
if (runlen > 127)
runlen -= 256;
if (runlen >= 0) {
runlen++;
FRead (rp, runlen, filenum);
rp += runlen;
linebytes -= runlen;
}
else {
runlen = -runlen + 1;
linebytes -= runlen;
pixel = getc (ftrip[filenum]);
do
*(rp++) = pixel;
while (--runlen);
}
}
}
/*
* read raster line from one of the color files
*/
void LoadRaster(raster, ByteWidth, filenum)
char *raster[6];
int ByteWidth, filenum;
{
if(bmhd[filenum].compress = 0) {
FRead (raster, ByteWidth * depth, filenum);
}
else {
short i;
for( i = 0; i < depth; i++) {
ReadDecomLine( ByteWidth, raster[i], filenum);
}
}
}
/*
* write intensity values for a given gun
* note: I've made dirty assumption about byte ordering in a short word
* if you run this on an ibm (ha ha ha) you'll have to change it
*/
#define ChipSize 4
void SaveRaster( raster, width, prim)
char *raster[];
int width, prim;
{
short i, j;
unsigned short val;
for( i = 0; i < width; i += ChipSize ) {
val = colmap[prim][GetIlbmVal(raster, i+3)][prim] << ChipSize;
val |= colmap[prim][GetIlbmVal(raster, i+2)][prim];
fputc( val&0xff, fout);
val = colmap[prim][GetIlbmVal(raster, i+1)][prim] << ChipSize;
val |= colmap[prim][GetIlbmVal(raster, i+0)][prim];
fputc( val&0xff, fout);
}
}
/*
* translate body of file to format RAY2 likes
*/
void TranslateRay2Body()
{
int BytesWidth;
int row, height, width, plane, prim;
char *raster[6];
depth = bmhd[0].npl;
width = bmhd[0].w;
height = bmhd[0].h;
BytesWidth = (width + 7)/8 ;
for( plane = 0; plane < bmhd[0].npl; plane++ ) {
raster[plane] = (char *)malloc(BytesWidth);
}
for( row = 0; !FileError && row < height; row++ ) {
fputc((unsigned char)(row>>8),fout); /* write line number */
fputc((unsigned char)(row&0xff),fout);
for( prim = RED; prim <= BLU; prim++ ) {
LoadRaster( raster, BytesWidth, prim);
SaveRaster( raster, width, prim);
}
}
}
main(argc, argv)
int argc;
char *argv[];
{
char buff[4][80];
char *extensions = "rgb";
int i;
if( argc == 1 || *argv[1] == '?' ) {
fprintf(stderr,"usage: merge filename\n");
exit(-1);
}
FileError = false;
for( i = 0; i < NumPrims; i++ ) {
sprintf(buff[i], "%s.%c", argv[1], extensions[i]);
nametrip[i] = buff[i];
ftrip[i] = fopen(nametrip[i],"r");
if(!ftrip[i]) {
fprintf(stderr,"unable to read %s\n", nametrip[i]);
FileError = true;
}
}
sprintf(buff[3], "%s.tmp", argv[1]);
oname = (argc>2)? argv[2]: buff[3];
fout = fopen( oname,"w");
if(!fout) {
fprintf(stderr,"unable to write to %s\n", oname);
FileError = true;
}
if( FileError ) goto ErrorExit;
for( i = 0; i < NumPrims; i++ ) {
printf("reading header %d\n", i);
ReadIffHeaders(i);
}
for( i = 1; i < NumPrims; i++ ) {
if( CmpBMHD(&bmhd[0], &bmhd[i])) {
fprintf(stderr,"image sizes differ(r != %d)\n", i);
FileError = true;
}
}
if( FileError ) goto ErrorExit;
printf("about to translate body\n");
TranslateRay2Body();
ErrorExit:
for( i = 0; i < NumPrims; i++) {
if(ftrip[i]) fclose( ftrip[i] );
}
if(fout) fclose(fout);
}
\Rogue\Monster\
else
echo "will not over write ./mergergb.c"
fi
if `test ! -s ./mergergb.lnk`
then
echo "writing ./mergergb.lnk"
cat > ./mergergb.lnk << '\Rogue\Monster\'
ROOT lib:c.o
MergeRGB.o
LIBRARY LIB:lc.lib
Lib:lcm.lib
LIB:amiga.lib
TO MergeRGB
verbose
nodebug
\Rogue\Monster\
else
echo "will not over write ./mergergb.lnk"
fi
if `test ! -s ./mouse.c`
then
echo "writing ./mouse.c"
cat > ./mouse.c << '\Rogue\Monster\'
#include "scrnio.ih"
#ifdef MANX
#include <functions.h>
#endif
#include "scrnio.h"
#include "mytypes.h"
#include "bezpt.h"
#include "control.h"
static bool buttondown; /* is left button down */
static short mousex, mousey;
static bool isleftbut; /* left button or pseudo middle button */
void HandleTicks(mesg)
struct IntuiMessage *mesg;
{
int x, y;
x = CntrX(mesg->MouseX);
y = CntrY(mesg->MouseY);
if(!buttondown || (mousex == x && mousey == y )){
return;
}
mousex = x;
mousey = y;
switch( CurMode ) {
case DRAWPOLY:
EditBezPt( mousex, mousey);
break;
case FITBEZIER:
/*
* need to select between the two
*/
if( isleftbut ) {
EditControl0(mousex, mousey);
}
else {
EditControl1(mousex, mousey);
}
break;
default:
break;
}
}
void HandleMButtons(mesg)
struct IntuiMessage *mesg;
{
long leftdist, rightdist;
long tx, ty;
mousex = CntrX(mesg->MouseX);
mousey = CntrY(mesg->MouseY);
switch( mesg->Code) {
case SELECTDOWN:
buttondown = true; /* down */
switch( CurMode ) {
case DRAWPOLY:
InitBezPt( mousex, mousey);
if( GetNumSegs() == 0 ) {
InitBezPt( mousex, mousey );
}
break;
case FITBEZIER:
tx = mousex - Cntrl1X(GetCurSeg());
ty = mousey - Cntrl1Y(GetCurSeg());
leftdist = tx *tx + ty * ty;
tx = mousex - Cntrl2X(GetCurSeg());
ty = mousey - Cntrl2Y(GetCurSeg());
rightdist = tx *tx + ty * ty;
if( isleftbut = (leftdist <= rightdist) ) {
EditControl0( mousex, mousey );
}
else {
EditControl1( mousex, mousey );
}
break;
default:
break;
}
break;
case SELECTUP:
buttondown = false; /* up */
break;
case MENUUP:
if( CurMode == FITBEZIER ) {
DrawControl0();
DrawControl1();
NextSeg();
DrawControl0();
DrawControl1();
}
break;
default:
break;
}
}
\Rogue\Monster\
else
echo "will not over write ./mouse.c"
fi
if `test ! -s ./mytypes.h`
then
echo "writing ./mytypes.h"
cat > ./mytypes.h << '\Rogue\Monster\'
#ifndef MYTYPES_H_FILE
#define MYTYPES_H_FILE
#define true 1
#define false 0
typedef char bool;
extern char *calloc(), *malloc();
#define null 0L
#ifndef MANX
#include "exec/types.h"
#include "libraries/mathffp.h"
#define ceil SPCeil
#define floor SPFloor
#define fabs SPAbs
#endif
#endif MYTYPES_H_FILE
\Rogue\Monster\
else
echo "will not over write ./mytypes.h"
fi
if `test ! -s ./packer.c`
then
echo "writing ./packer.c"
cat > ./packer.c << '\Rogue\Monster\'
/*
* this file is a hacked up version of the original, who blurb is below
* changes made: internal buffer no longer static, but is now on stack
*/
/*----------------------------------------------------------------------*
* packer.c Convert data to "cmpByteRun1" run compression. 11/15/85
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* control bytes:
* [0..127] : followed by n+1 bytes of data.
* [-1..-127] : followed by byte to be repeated (-n)+1 times.
* -128 : NOOP.
*
* This version for the Commodore-Amiga computer.
*----------------------------------------------------------------------*/
#include <exec/types.h>
#define DUMP 0
#define RUN 1
#define MinRun 3
#define MaxRun 128
#define MaxDat 128
static short putSize;
#define GetByte() (*source++)
#define PutByte(c) { *dest++ = c; ++putSize; }
static BYTE *buf; /* [TBD] should be 128? on stack?*/
static BYTE *PutDump(dest, nn)
BYTE *dest;
int nn;
{
int i;
PutByte(nn-1);
for(i = 0; i < nn; i++) PutByte(buf[i]);
return(dest);
}
static BYTE *PutRun(dest, nn, cc)
BYTE *dest;
int nn, cc;
{
PutByte(-(nn-1));
PutByte(cc);
return(dest);
}
#define OutDump(nn) dest = PutDump(dest, nn)
#define OutRun(nn,cc) dest = PutRun(dest, nn, cc)
/*----------- PackRow --------------------------------------------------*/
/* Given POINTERS TO POINTERS, packs one row, updating the source and
destination pointers. RETURNs count of packed bytes.*/
int PackRow(source, dest, rowSize)
BYTE *source, *dest;
int rowSize;
{
char innerbuf[256];
char c,lastc = '\0';
BOOL mode = DUMP;
short nbuf = 0; /* number of chars in buffer */
short rstart = 0; /* buffer index current run starts */
/*
* cute way to make local buffer known to external procedures
* since static variables increase executable size in Manx
*/
buf = innerbuf; /* way to put make local buffer known to external procs */
putSize = 0;
buf[0] = lastc = c = GetByte(); /* so have valid lastc */
nbuf = 1; rowSize--; /* since one byte eaten.*/
for (; rowSize; --rowSize) {
buf[nbuf++] = c = GetByte();
switch (mode) {
case DUMP:
/* If the buffer is full, write the length byte,
then the data */
if (nbuf>MaxDat) {
OutDump(nbuf-1);
buf[0] = c;
nbuf = 1; rstart = 0;
break;
}
if (c == lastc) {
if (nbuf-rstart >= MinRun) {
if (rstart > 0) OutDump(rstart);
mode = RUN;
}
else if (rstart == 0)
mode = RUN; /* no dump in progress,
so can't lose by making these 2 a run.*/
}
else rstart = nbuf-1; /* first of run */
break;
case RUN: if ( (c != lastc)|| ( nbuf-rstart > MaxRun)) {
/* output run */
OutRun(nbuf-1-rstart,lastc);
buf[0] = c;
nbuf = 1; rstart = 0;
mode = DUMP;
}
break;
}
lastc = c;
}
switch (mode) {
case DUMP: OutDump(nbuf); break;
case RUN: OutRun(nbuf-rstart,lastc); break;
}
return(putSize);
}
\Rogue\Monster\
else
echo "will not over write ./packer.c"
fi
if `test ! -s ./poly.c`
then
echo "writing ./poly.c"
cat > ./poly.c << '\Rogue\Monster\'
#include <math.h>
#include "mytypes.h"
#include "scrnio.h"
#include "bezpt.h"
#include "revolve.h"
#include "control.h"
#include "poly.h"
#include "readilbm.h"
#include "menuexp.h"
bool SpecOn = false; /* specular lighting enable - default off */
float Ambience = DefAmbience;
float PtIntensity = (float)DefIntensity;
float Kd = DefKd,
Ks = DefKs;
Pt3 LightSrc = {
DefLightSrcX,
DefLightSrcY,
DefLightSrcZ
};
static
Rhomboid *polylist = null,
*nextpoly;
MapRhomboid *mpolylist = null,
*mnextpoly;
static
int polyspace = 0;
static bool shadeflag;
long CalcMaxPolyNum() {
return( GetNumSegs() * BezMesh * RevMesh );
}
static
bool PrepPoly()
{
if( polylist ) free( (char *)polylist );
polylist = (Rhomboid *)malloc( CalcMaxPolyNum() * sizeof(Rhomboid));
if( !polylist ) {
OutErr("PrepPoly: not enough memory");
return( true );
}
nextpoly = polylist;
return(false); /* success = 0 */
}
static bool
PrepMPoly()
{
if( mpolylist ) free( (char *)mpolylist );
mpolylist = (MapRhomboid *)
malloc( CalcMaxPolyNum() * sizeof(MapRhomboid));
if( !mpolylist ) {
OutErr("PrepPoly: not enough memory");
return( true );
}
mnextpoly = mpolylist;
return(false); /* success = 0 */
}
/*
* Multiply a vector by scalar quantity
*/
void ScaleVec( fact, src, dst )
float fact;
Pt3 *src, *dst;
{
dst->x = src->x * fact;
dst->y = src->y * fact;
dst->z = src->z * fact;
}
/*
* convert a vector to a unitized vector
* if possible
*/
void Unitize( vec )
Pt3 *vec;
{
float len;
len = vec->x*vec->x + vec->y*vec->y + vec->z*vec->z;
len = sqrt( len );
if( len != 0.0 ) {
vec->x /= len;
vec->y /= len;
vec->z /= len;
}
}
/*
* calculate a vector from two points
*/
void CalcVector( src1, src2, dest )
Pt3 *src1, *src2, *dest ;
{
dest->x = src1->x - src2->x;
dest->y = src1->y - src2->y;
dest->z = src1->z - src2->z;
}
/*
* calculate a normal from a list of polygons. This routine does the
* logical trick of trying to exclude each point in turn if the
* normal can not be calculated, or something of the sort.
* a value of true is returned if a normal with a nonzero z component
* could not be calculated
*/
bool CalcNormal( vxlist, normal)
PtGen *vxlist[];
register Pt3 *normal;
{
int i, k, m;
Pt3 *j[3];
Pt3 v1, v2;
for( i = 0; i < RhomVxNum; i++ ) {
for( k = 0, m = 3; m--; k++ ) {
if( k == i ) {
k++;
}
j[m] = &vxlist[k]->d3;
}
CalcVector( j[1], j[0], &v1 );
CalcVector( j[2], j[1], &v2 );
normal->z = v1.x*v2.y - v1.y*v2.x;
if( normal->z == 0 ) {
continue;
}
normal->x = v1.y*v2.z - v1.z*v2.y;
normal->y = v1.z*v2.x - v1.x*v2.z;
if( normal->z < 0 ) {
normal->x = -normal->x;
normal->y = -normal->y;
normal->z = -normal->z;
}
Unitize(normal);
return( false );
}
return(true);
}
/*
* Euclidean dot product.
* I wonder what the minkowski dot product would look like
*/
float DotProd( v1, v2 )
Pt3 *v1, *v2;
{
return( v1->x*v2->x + v1->y*v2->y + v1->z*v2->z );
}
/*
* define a polygon as a set of four points
* returns true if polygon created
*/
static bool CreatePoly(curpoly, p0, p1, p2, p3)
register Rhomboid *curpoly;
PtGen *p0, *p1, *p2, *p3;
{
Pt3 normal;
PtGen *list[RhomVxNum];
list[0] = p0; list[1] = p1; list[2] = p2; list[3] = p3;
/*
* compute stuff needed only if producing shaded image
*/
if( shadeflag ) {
Pt3 lvec;
Pt3 center;
float ptintens;
float ldotn; /* light vector dot normal */
/*
* if cant compute normal, then junk polygon
*/
if( CalcNormal( list, &normal )) {
return(false);
}
curpoly->intensity = Ambience;
center.x = ( list[0]->d3.x
+ list[1]->d3.x
+ list[2]->d3.x
+ list[3]->d3.x)/4.0;
center.y = ( list[0]->d3.y
+ list[1]->d3.y
+ list[2]->d3.y
+ list[3]->d3.y)/4.0;
center.z = ( list[0]->d3.z
+ list[1]->d3.z
+ list[2]->d3.z
+ list[3]->d3.z)/4.0;
curpoly->depth = center.z;
CalcVector( ¢er, &LightSrc, &lvec );
Unitize( &lvec );
ldotn = DotProd( &lvec, &normal );
if( ldotn < 0 ) {
ptintens = PtIntensity * Kd * -ldotn;
curpoly->intensity += ptintens;
}
/*
* calculate specular component
*/
if( SpecOn && ldotn < 0 ) {
float Kspec, Is;
Pt3 rvec; /* lvec reflected through poly */
ScaleVec( 2*ldotn, &normal, &rvec );
CalcVector(&lvec, &rvec, &rvec );
Unitize( ¢er );
Kspec = DotProd( &rvec, ¢er);
if( Kspec <= 0.0 ) {
Is = Ks * Kspec * Kspec* PtIntensity;
curpoly->intensity += Is;
}
}
if( curpoly->intensity > 1.0 ) {
curpoly->intensity = 1.0;
}
}
else {
/*
* calculate depth of polygon
* for now, try an average of the vertex depths
*/
curpoly->depth =( list[0]->d3.z
+ list[1]->d3.z
+ list[2]->d3.z
+ list[3]->d3.z)/4.0;
}
/*
* store index to screen coordinates
*/
curpoly->pt[0] = p0->d2;
curpoly->pt[1] = p1->d2;
curpoly->pt[2] = p2->d2;
curpoly->pt[3] = p3->d2;
return(true);
}
/*
* passable procedure for creating polygons without mapping
*/
static
void AcceptPoly(p0, p1, p2, p3)
PtGen *p0, *p1, *p2, *p3;
{
if( CreatePoly(nextpoly, p0, p1, p2,p3)) {
nextpoly++;
}
}
static
void AcceptMPoly( p0, p1, p2, p3)
PtGen *p0, *p1, *p2, *p3;
{
if( CreatePoly(&mnextpoly->rhom, p0, p1, p2,p3)) {
mnextpoly->bezindex = RevImageB;
mnextpoly->revindex = RevImageR;
mnextpoly++;
}
}
/*
* compare the depth of two polygons for SortPoly
*/
static int CmpDepth( a, b )
Rhomboid *a, *b;
{
if( a->depth < b->depth ) return(-1);
else if( a->depth > b->depth ) return(1);
else return(0);
}
static int CmpMDepth( a, b )
MapRhomboid *a, *b;
{
if( a->rhom.depth < b->rhom.depth ) return(-1);
else if( a->rhom.depth > b->rhom.depth ) return(1);
else return(0);
}
void RevNoShade() {
Rhomboid *i;
if( GetNumSegs() < 1 ) {
return;
}
CurMode = NOTACTIVE;
ClrAbort();
shadeflag = false;
if( PrepPoly() ) return;
if( Revolve(AcceptPoly) ) return;
qsort( (char *)polylist, nextpoly - polylist,
sizeof(Rhomboid), CmpDepth);
ClrWindow(false);
for( i = polylist; i< nextpoly; i++ ) {
if( AbortDraw ) return;
DrawRhomFrame( i->pt );
}
}
void RevShade() {
register Rhomboid *i;
if( GetNumSegs() < 1 ) {
return;
}
CurMode = NOTACTIVE;
ClrAbort();
shadeflag = true;
if( PrepPoly() || Revolve(AcceptPoly) ) {
return;
}
qsort( (char *)polylist, nextpoly-polylist,
sizeof(Rhomboid), CmpDepth);
ClrWindow(false);
for( i = polylist; i< nextpoly; i++ ) {
if( AbortDraw ) return;
DrawRhomShade( i );
}
}
void RevMap() {
register MapRhomboid *i;
if( GetNumSegs() < 1 ) {
return;
}
if( InitMapping() ) {
return;
}
ClrAbort();
CurMode = NOTACTIVE;
shadeflag = true;
if( PrepMPoly() || Revolve(AcceptMPoly) ) {
return;
}
qsort( (char *)mpolylist, mnextpoly-mpolylist,
sizeof(MapRhomboid), CmpMDepth);
ClrWindow(false);
for( i = mpolylist; i< mnextpoly; i++ ) {
if( AbortDraw ) return;
DrawRhomMap(i);
}
}
\Rogue\Monster\
else
echo "will not over write ./poly.c"
fi
if `test ! -s ./poly.h`
then
echo "writing ./poly.h"
cat > ./poly.h << '\Rogue\Monster\'
#ifndef POLY_H_FILE
#define POLY_H_FILE
#include <exec/types.h>
#include "mytypes.h"
#include "revolve.h"
#define RhomVxNum 4
typedef struct {
ScrnPair pt[RhomVxNum];
float depth;
float intensity;
} Rhomboid;
typedef struct {
Rhomboid rhom;
short bezindex,
revindex;
} MapRhomboid;
extern bool SpecOn;
#define DefLightSrcX 0.0
#define DefLightSrcY 0.0
#define DefLightSrcZ 0.0
#define DefIntensity 0.8
#define DefAmbience 0.15
#define DefKd 0.8
#define DefKs 0.2
extern float Ambience,
PtIntensity,
Kd, Ks;
extern Pt3 LightSrc;
extern void RevNoShade();
extern void RevShade();
extern void RevMap();
#endif !POLY_H_FILE
\Rogue\Monster\
else
echo "will not over write ./poly.h"
fi
if `test ! -s ./readilbm.c`
then
echo "writing ./readilbm.c"
cat > ./readilbm.c << '\Rogue\Monster\'
#include <stdio.h>
#include <ctype.h>
#include "readilbm.h"
#define FALSE 0
#define TRUE 1
#define RED 0
#define GRN 1
#define BLU 2
/* color to grey conversion methods */
#define AVERAGE 0
#define LUMIN 1
#define DIST 2
#define REDONLY 3
#define GREENONLY 4
#define BLUEONLY 5
#define MakeID(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) )
#define ID_FORM MakeID('F','O','R','M')
#define ID_ILBM MakeID('I','L','B','M')
#define ID_BMHD MakeID('B','M','H','D')
#define ID_CMAP MakeID('C','M','A','P')
#define ID_CAMG MakeID('C','A','M','G')
#define ID_BODY MakeID('B','O','D','Y')
#define ROUNDUP(x) ( ((x)+1) & (~1L) )
static struct CHUNK {
unsigned long Id, Size;
} Chunk;
static unsigned char cmap[32][3];
struct BMHD {
short w,h,x,y;
char npl,mask,compress,pad1;
short transparentColor;
char xAspect,yAspect;
short pageWidth,pageHeight;
};
static short Color[32], /* output colors */
Method = AVERAGE; /* color conversion */
static short numcolors;
static
FILE *fin; /* input file */
extern char *malloc();
static void FRead();
static void ReadBMHD();
static void ReadChunk();
static void RastOut();
static void HamOut();
static char GetIlbmVal();
static void InitColorMappings();
static short Convert();
static void ReadDecomLine();
static void ProcessRows();
#define ABORT(str) { OutErr(str); goto ErrorExit; }
void SetGreyModel( model )
int model;
{
Method = model;
}
/*
* main routine for reading in an iff file
*/
void ReadIlbm(filename)
char *filename;
{
struct BMHD bmhd;
long ILBMid;
unsigned char cmapFlag = FALSE,
bmhdFlag = FALSE;
if ((fin = fopen (filename, "r")) == NULL) {
OutErr ("ERROR: cannot open input file");
return;
}
/* read in iff file */
ReadChunk ();
if (Chunk.Id != ID_FORM)
ABORT ("Not an IFF File");
FRead (&ILBMid, 4);
if (ILBMid != ID_ILBM)
ABORT ("Not an ILBM File");
while (1) {
long camgdata;
ReadChunk ();
if (Chunk.Id == ID_BODY)
break;
if( feof( fin ) ) {
ABORT("reached end of file without seeing body\n");
}
switch (Chunk.Id) {
case ID_CMAP:
FRead (cmap, Chunk.Size);
numcolors = Chunk.Size/3;
cmapFlag = TRUE;
break;
case ID_BMHD:
ReadBMHD (&bmhd);
bmhdFlag = TRUE;
break;
case ID_CAMG:
FRead( &camgdata, sizeof(camgdata) );
break;
default: /* unknown identifier */
fseek( fin, Chunk.Size, 1);
break;
}
}
if (!cmapFlag) {
ABORT("IFF file does not contain a CMAP chunk before the BODY\n");
}
if (!bmhdFlag) {
ABORT("IFF file does not contain a BMHD chunk before the BODY\n");
}
InitColorMappings();
if( OpenImgPix( bmhd.w, bmhd.h, Convert(0xf, 0xf, 0xf)) ) {
ProcessRows(&bmhd);
}
ErrorExit:
fclose( fin);
}
static void ProcessRows(bmhd)
struct BMHD *bmhd;
{
char *rastlist[6];
char *Raster;
int depth, i, v, pixwidth;
int BytePerLine;
depth = bmhd->npl;
pixwidth = bmhd->w;
BytePerLine =(pixwidth+7) / 8;
Raster = (char *) malloc (BytePerLine * depth);
if(!Raster ) {
OutErr("ProcessRows:could not allocate Raster");
return;
}
for( i = 0; i < depth; i++ ) {
rastlist[i] = Raster + BytePerLine*i;
}
for( v = 0; v < bmhd->h; v++) {
switch (bmhd->compress) {
case 0:
FRead (Raster, BytePerLine * depth);
break;
case 1:
for( i = 0; i < depth; i++) {
ReadDecomLine( BytePerLine, rastlist[i]);
}
break;
default:
ABORT ("Unknown Compression type in BODY");
}
if(depth == 6 ) {
HamOut( rastlist, pixwidth, v);
}
else {
RastOut( rastlist, pixwidth, v, depth);
}
}
ErrorExit:
if( Raster ) free(Raster);
}
static void ReadDecomLine(linebytes, rp)
int linebytes;
char *rp;
{
int runlen;
char pixel;
while (linebytes) {
runlen = getc (fin);
if (runlen > 127)
runlen -= 256;
if (runlen >= 0) {
runlen++;
FRead (rp, runlen);
rp += runlen;
linebytes -= runlen;
}
else {
runlen = -runlen + 1;
linebytes -= runlen;
pixel = getc (fin);
do
*(rp++) = pixel;
while (--runlen);
}
}
}
/*
* Convert - convert (r,g,b) to hex greyscale.
*/
static short Convert(r,g,b)
unsigned char r,g,b;
{
short i,
rd, gd, bd,
min,
dist,
best;
/* convert color according to 'Method' */
switch (Method) {
case AVERAGE: /* average r,g,b to obtain grey level */
return ((r + g + b) / 3);
case LUMIN: /* use NTSC luminescence as grey level */
return ((r * 30 + g * 59 + b * 11) / 100);
case DIST: /* use grey with minimum distance in color */
min = 15*15 * 3;
for( i = 0; i < numcolors; i++ ) {
rd = r -i;
gd = g - i;
bd = b - i;
dist = rd * rd + gd * gd + bd * bd;
if( dist < min ) {
min = dist; best = i;
}
}
return( best );
case REDONLY:
return(r);
case GREENONLY:
return(g);
case BLUEONLY:
return(b);
}
} /* Convert */
static void InitColorMappings()
{
int i;
/* put colors in 4-bit range and Convert */
for (i = 0; i < 32; i++) {
cmap[i][RED] >>= 4;
cmap[i][GRN] >>= 4;
cmap[i][BLU] >>= 4;
Color[i] = Convert (cmap[i][RED], cmap[i][GRN], cmap[i][BLU]);
}
}
/*
* leftmost pixel of byte is in most significant bit of byte
*/
static char GetIlbmVal( rastlist, h, bpp )
char *rastlist[6];
int h, bpp;
{
int i;
char value = 0;
short mask, bytep;
mask = 0x80 >> ( h & 7);
bytep = h >> 3;
for( i = bpp-1; i >= 0; i-- ) {
value <<= 1;
value |= (*(rastlist[i]+bytep) & mask) ? 1: 0;
}
return( value );
}
/*
* HamOut - output ham image in hex.
*/
static void HamOut(rastlist, pixwidth, v)
char *rastlist[6];
int pixwidth, v;
{
unsigned char lastred = 0,
lastgreen = 0,
lastblue = 0;
int h;
char pixval;
for( h = 0; h <pixwidth; h++ ) {
short shade;
shade = GetIlbmVal(rastlist, h, 6);
pixval = shade & 0x0F;
switch (shade & 0x30) {
case 0x00:
lastred = cmap[pixval][RED];
lastgreen = cmap[pixval][GRN];
lastblue = cmap[pixval][BLU];
shade = Color[pixval];
break;
case 0x10:
lastblue = pixval;
shade = Convert(lastred,lastgreen,lastblue);
break;
case 0x20:
lastred = pixval;
shade = Convert(lastred,lastgreen,lastblue);
break;
case 0x30:
lastgreen = pixval;
shade = Convert(lastred,lastgreen,lastblue);
}
SetImgPix(h, v, shade);
}
}
/*
* RastOut - handle normal bit mapped images
*/
static void RastOut(rastlist, pixwidth, v, depth)
char *rastlist[6];
int pixwidth, v, depth;
{
int h, bit;
for( h = 0; h < pixwidth; h++ ) {
short shade;
shade = Color[GetIlbmVal( rastlist, h, depth)];
SetImgPix( h, v, shade);
}
}
/*
* ReadChunk - read in an IFF Chunk.
*/
static void ReadChunk()
{
FRead (&Chunk, sizeof (Chunk));
} /* ReadChunk */
/*
* ReadBMHD - read the BMHD structure.
*/
static void ReadBMHD(bmhd)
struct BMHD *bmhd;
{
FRead (bmhd, Chunk.Size);
} /* ReadBMHD */
/*
* FRead - read 'len' bytes to 'pointer' while checking for an error.
*/
static void FRead(pointer,len)
char *pointer;
int len;
{
if (fread (pointer, len, 1, fin) == 0) {
char outbuff[90];
sprintf(outbuff,"Fread Error in reading input file at %d ", ftell(fin));
OutErr(outbuff);
}
} /* FRead */
\Rogue\Monster\
else
echo "will not over write ./readilbm.c"
fi
if `test ! -s ./readilbm.h`
then
echo "writing ./readilbm.h"
cat > ./readilbm.h << '\Rogue\Monster\'
#ifndef READILBM_H_FILE
#define READILBM_H_FILE
#ifndef MYTYPES_H_FILE
#include "mytypes.h"
#endif MYTYPES_H_FILE
#define DefRepV 1
#define DefRepH 1
/*
* how many times the image should be replicated on screen
*/
extern short MapRepV, MapRepH;
/*
* Size of image read in
*/
extern int MapImageV, MapImageH;
/*
* ReadPixel returns an intensity between 0-255
*/
extern short GetImgPix(/* short vert, hori */);
extern void CloseImgPix();
bool OpenImgPix( /* int sizex, sizey; short maxshade */);
void SetImgPix( /* int x, y; short val */ );
short GetImgPix( /* int x, y */);
extern void PrepImgPix(/* void */);
#define DefXYFlip false
extern void FlipImgPix( /* bool flip */);
extern void SetGreyModel( /* int */);
#endif READILBM_H_FILE
\Rogue\Monster\
else
echo "will not over write ./readilbm.h"
fi
if `test ! -s ./revolve.c`
then
echo "writing ./revolve.c"
cat > ./revolve.c << '\Rogue\Monster\'
#include <math.h>
#include "fasttrig.h"
#include "bezpt.h"
#include "revolve.h"
#include "mytypes.h"
RevAxisType RevAxis;
short RevMesh = DefRevMeshVal;
short RevImageR, /* revolution index */
RevImageB; /* bezier index */
static int RotRange = DefRotRange;
static int RotStart = DefRotStart;
static int SecAngle = DefTilt;
static float SurfDist = DefSurfDist;
static float ViewDist = DefViewDist;
static bool Perspective = DefPersp;
void SetPerspective( value)
int value;
{
Perspective = value;
}
void SetRevAxis( value)
int value;
{
RevAxis = (value)? RevY : RevX;
}
void SetRotStart( value )
int value;
{
RotStart = value;
}
void SetRotRange( value )
int value;
{
RotRange = value;
}
void SetSecAng( value )
int value;
{
SecAngle = value;
}
void SetRevMesh( value )
int value;
{
RevMesh = value;
}
void SetSurfDist( value )
int value;
{
SurfDist = (float )value;
}
void SetViewDist( value )
int value;
{
ViewDist = (float )value;
}
static
float secsin, seccos; /* trig values of secondary angle */
static
int sizeptlist = 0;
static
PtGen *ptlist1 = 0,
*ptlist2 = 0;
static
int NumEnts; /* number of angle slices */
static
bool PrepRev()
{
NumEnts = RevMesh+1;
/*
* allocate space 3d descriptions of a point revolved x degrees
*/
if( NumEnts > sizeptlist ) {
if( ptlist1 ) free(ptlist1);
if( ptlist2 ) free(ptlist2);
ptlist1 =(PtGen *) malloc( NumEnts * sizeof(PtGen) );
ptlist2 =(PtGen *) malloc( NumEnts * sizeof(PtGen) );
if( !ptlist1 || !ptlist2 ) {
OutErr("PrepRev:not enough memory");
return(true);
}
}
if( InitFastTrig( RotStart, RotRange, NumEnts)) return(true);
secsin = sin((float)SecAngle*PI/180);
seccos = cos((float)SecAngle*PI/180);
return (false);
}
static
void CalcRing(ptlist, xpos, ypos)
register PtGen *ptlist;
float xpos, ypos;
{
int angle;
for( angle = 0; angle < NumEnts; angle++, ptlist++) {
float temp;
/*
* calculate 3d coordinate of point revolved
*/
if( RevAxis == RevX) {
ptlist->d3.y = ypos * fcos(angle);
temp = ypos * fsin(angle);
ptlist->d3.x = xpos* seccos - temp *secsin;
ptlist->d3.z = xpos * secsin + temp * seccos;
}
else {
ptlist->d3.x = xpos * fcos(angle);
temp = xpos * fsin( angle);
ptlist->d3.y = ypos * seccos + temp * secsin;
ptlist->d3.z = secsin * ypos - temp * seccos;
}
ptlist->d3.z -= SurfDist;
if( Perspective ) {
float PerspScale;
PerspScale = fabs(ViewDist / ptlist->d3.z);
ptlist->d3.x *= PerspScale;
ptlist->d3.y *= PerspScale;
}
/*
* calculate the 2d screen coordinate equvalent
*/
/*
ptlist->d2.x = (short) ptlist->d3.x;
ptlist->d2.y = (short) ptlist->d3.y;
*/
ptlist->d2.x = (short) (ptlist->d3.x + 0.5);
ptlist->d2.y = (short) (ptlist->d3.y + 0.5);
}
}
/*
* return true on failure
*/
bool Revolve(acceptfunc)
void (*acceptfunc)();
{
int segno;
float tparm, deltat;
int angle;
int subseg;
if( PrepRev() ) {
return(true);
}
deltat = 1.0/BezMesh;
RevImageB = 0;
ResetActSeg();
do {
float xpos, ypos;
InitCalcBez();
xpos = StartPtX(GetCurSeg());
ypos = StartPtY(GetCurSeg());
CalcRing(ptlist1, xpos, ypos );
for( subseg = 1; subseg <= BezMesh; subseg++ ) {
register PtGen *ptlista, *ptlistb;
register int numpoly;
tparm = subseg * deltat;
if( subseg & 1 ) {
ptlista = ptlist2; ptlistb = ptlist1;
}
else {
ptlista = ptlist1; ptlistb = ptlist2;
}
CalcBezPt(tparm, &xpos, &ypos );
CalcRing( ptlista, xpos, ypos );
RevImageR = 0;
for( numpoly = NumEnts -1; numpoly--; ) {
/* (* acceptfunc)(ptlista, ptlista+1, ptlistb+1, ptlistb); */
(* acceptfunc)(ptlistb, ptlista, ptlista+1, ptlistb+1);
ptlista++;
ptlistb++;
RevImageR++;
}
RevImageB++;
}
NextSeg();
} while( ActSeg );
return( false );
}
\Rogue\Monster\
else
echo "will not over write ./revolve.c"
fi
if `test ! -s ./revolve.h`
then
echo "writing ./revolve.h"
cat > ./revolve.h << '\Rogue\Monster\'
#ifndef REVOLVE_H_FILE
#define REVOLVE_H_FILE
#include "mytypes.h"
typedef enum { RevX, RevY } RevAxisType;
extern RevAxisType RevAxis;
#define DefRevMeshVal 30
#define DefSurfDist 3000
#define DefTilt 15
#define DefRotRange 360
#define DefRotStart 0
#define DefPersp false
#define DefViewDist 3000
typedef struct {
short x, y;
} ScrnPair;
typedef struct {
float x, y, z;
} Pt3;
typedef struct {
Pt3 d3;
ScrnPair d2;
} PtGen;
extern short RevMesh;
extern short RevImageR,
RevImageB;
extern void SetRotStart();
extern void SetRotRange(/* Panel_item, int, struct input_event */);
extern void SetSecAng(/* Panel_item, int, struct input_event */);
extern void SetPolyMode( /* Panel_item, int, struct input_event */);
extern void SetFitBez( /* Panel_item, int, struct input_event */);
extern bool Revolve( /* Panel_item, int, struct input_event */);
extern void SetRevAxis( /* Panel_item, int, struct input_event */);
extern void SetRevMesh( /* Panel_item, int, struct input_event */);
extern void SetSurfDist(/* Panel_item, int, struct input_event */);
extern void SetViewDist();
extern void SetPerspective();
#endif !REVOLVE_H_FILE
\Rogue\Monster\
else
echo "will not over write ./revolve.h"
fi
if `test ! -s ./scrndef.c`
then
echo "writing ./scrndef.c"
cat > ./scrndef.c << '\Rogue\Monster\'
/* this file contains definition for the screen */
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#ifdef MANX
#include <functions.h>
#endif
#include "scrndef.h"
struct TextAttr myfont1 = {
(UBYTE *)"topaz.font", 8, 0, 0
};
struct NewScreen SurfScrnDef = {
0,0, /* left and top edge */
SurfInitW, SurfInitH+ButHeight, /* width and height */
SurfInitD, /* num bitplanes bit planes */
0,1, /* detail, block pen */
SurfInitType, /* lores non interlaced */
CUSTOMSCREEN,
&myfont1,
NULL /*(UBYTE *) "Screen" */,
NULL,
NULL
};
struct NewWindow SurfWinDef = {
0, ButHeight, /* left, top */
SurfInitW, SurfInitH, /* width, height */
-1, -1, /* default detail and block pen */
MOUSEBUTTONS | MOUSEMOVE| INTUITICKS /* | CLOSEWINDOW */,
RMBTRAP | SIMPLE_REFRESH | GIMMEZEROZERO | BORDERLESS
| BACKDROP,
NULL, NULL, /* gadget, checkmark */
NULL /* (UBYTE *) "BezSurf - By Eric Davies" */,
NULL, /* pointer to screen */
NULL, /* pointer to super bitmap */
10, 10, 640, 200, /* min and max dimensions */
CUSTOMSCREEN
};
struct NewWindow GadWinDef = {
0, 0, /* left, top */
SurfInitW, ButHeight, /* width, height */
-1, 0, /* default detail and block pen */
GADGETUP,
SIMPLE_REFRESH | BORDERLESS | BACKDROP,
NULL, NULL, /* gadget, checkmark */
NULL /*(UBYTE *) "Gadwin" */,
NULL, /* pointer to screen */
NULL, /* pointer to super bitmap */
10, 10, 10, 10, /* min and max dimensions */
CUSTOMSCREEN
};
struct NewWindow CntrlWinDef = {
0, 0, /* left, top */
640, 180, /* width, height */
-1, -1, /* default detail and block pen */
CLOSEWINDOW| GADGETUP| MENUPICK,
SIMPLE_REFRESH | WINDOWCLOSE | WINDOWDEPTH
| WINDOWDRAG | WINDOWSIZING,
NULL, NULL, /* gadget(set by program), checkmark */
(UBYTE *) "BezSurf - Control Panel - By Eric Davies",
NULL, /* pointer to screen */
NULL, /* pointer to super bitmap */
10, 10, 640, 200, /* min and max dimensions */
WBENCHSCREEN
};
\Rogue\Monster\
else
echo "will not over write ./scrndef.c"
fi
if `test ! -s ./scrndef.h`
then
echo "writing ./scrndef.h"
cat > ./scrndef.h << '\Rogue\Monster\'
#ifndef SCRNDEF_H_FILE
#define SCRNDEF_H_FILE
#define ButHeight 10 /* height of GadWin */
#define SurfInitW 320 /* initial width */
#define SurfInitH 200 /* initial height */
#define SurfInitD 4 /* 16 color */
#define SurfInitType 0 /* Lores */
extern struct NewWindow SurfWinDef;
extern struct NewWindow CntrlWinDef;
extern struct NewScreen SurfScrnDef;
extern struct NewWindow GadWinDef;
#endif !SCRNDEF_H_FILE
\Rogue\Monster\
else
echo "will not over write ./scrndef.h"
fi
if `test ! -s ./scrnio.c`
then
echo "writing ./scrnio.c"
cat > ./scrnio.c << '\Rogue\Monster\'
/* main program */
#include "scrnio.ih"
/*#include <functions.h>*/
#include "scrndef.h"
#include "scrnio.h"
#include "gadgetdef.h"
#include "menudef.h"
struct Screen *SurfScrn = NULL;
struct Window *SurfWin = NULL;
struct Window *CntrlWin = NULL;
struct Window *GadWin = NULL;
/*
* bit masks for waiting for signals
*/
short CntrlSigBit, SurfSigBit, GadSigBit;
long SignalMask = 0;
struct RastPort *rp;
struct ViewPort *vp;
struct Library *GfxBase = 0,
*IntuitionBase = 0;
int XOR = COMPLEMENT, /* so my other modules don't need to */
WRITE = JAM1; /* include so many amiga includes */
int WinHOrig, WinVOrig;
int WinFgCol;
int ColorMax;
int NumColors;
/*
* data structures needed to use amiga polygons routines
*/
static WORD PolyArea[5*5];
static struct AreaInfo PolyInfo;
static PLANEPTR PolyWorkSpace;
static struct TmpRas PolyTmpRas;
static void ResetWinDat() {
WinHOrig = SurfWinDef.Width >>1;
WinVOrig = SurfWinDef.Height >>1;
rp = SurfWin->RPort;
SetDrMd( rp, JAM1 );
}
/*
* open surface window/screen
*/
OpenSurf() {
NumColors = 1 << SurfScrnDef.Depth;
ColorMax = ( NumColors -1) * 8 + 1;
WinFgCol = (NumColors - 1) & 0x1f;
SurfScrnDef.BlockPen = ( WinFgCol *3) /4;
SurfScrnDef.DetailPen = WinFgCol>>2;
SurfScrn = OpenScreen( &SurfScrnDef );
MenuSetColMap();
SurfWinDef.Screen = GadWinDef.Screen = SurfScrn;
SurfWinDef.Width = GadWinDef.Width = SurfScrnDef.Width;
SurfWinDef.Height = SurfScrnDef.Height - ButHeight;
SurfWin = OpenWindow( &SurfWinDef );
GadWin = OpenWindow( &GadWinDef );
SurfSigBit = SurfWin->UserPort->mp_SigBit;
GadSigBit = GadWin->UserPort->mp_SigBit;
SignalMask = (1<<CntrlSigBit) | (1<<SurfSigBit)| (1<<GadSigBit);
ResetWinDat();
ShowTitle( SurfScrn, 0L ); /* hide screen title behind backdrop */
InitArea( &PolyInfo, PolyArea, 5);
rp->AreaInfo = &PolyInfo;
PolyWorkSpace = AllocRaster( SurfWinDef.Width, SurfWinDef.Height);
if( !PolyWorkSpace ) {
CloseDisplay();
perror("no space for temporary rastern");
exit(0);
}
else {
InitTmpRas( &PolyTmpRas, PolyWorkSpace,
RASSIZE( SurfWinDef.Width, SurfWinDef.Height ));
rp->TmpRas = &PolyTmpRas;
}
}
void InitWindow()
{
GfxBase = OpenLibrary("graphics.library",0);
if( GfxBase == 0 ) {
OutErr("graphics library won't open");
exit(10);
}
IntuitionBase = OpenLibrary("intuition.library",0);
if( IntuitionBase == 0 ) {
OutErr("intuition library won't open");
exit(10);
}
InitGadgets();
CntrlWin = OpenWindow( &CntrlWinDef );
CntrlSigBit = CntrlWin->UserPort->mp_SigBit;
MenuSetScrn();
if( !SurfScrn || !SurfWin || !CntrlWin ) {
OutErr("couldn't open at least one window or screen");
CloseDisplay();
exit( 0 );
}
SetMenuStrip(CntrlWin, menu );
}
/*
* remove surface window/screen
*/
CloseSurf() {
if( PolyWorkSpace)
FreeRaster( PolyWorkSpace, SurfWinDef.Width, SurfWinDef.Height );
if( SurfWin )
CloseWindow( SurfWin );
if( GadWin )
CloseWindow( GadWin );
if( SurfScrn )
CloseScreen( SurfScrn );
}
void CloseDisplay()
{
CloseSurf();
if( CntrlWin ) {
ClearMenuStrip( CntrlWin );
CloseWindow( CntrlWin );
}
EndGadgets();
if ( IntuitionBase )
CloseLibrary(IntuitionBase);
if ( GfxBase )
CloseLibrary(GfxBase);
}
\Rogue\Monster\
else
echo "will not over write ./scrnio.c"
fi
if `test ! -s ./scrnio.h`
then
echo "writing ./scrnio.h"
cat > ./scrnio.h << '\Rogue\Monster\'
extern void InitWindow();
extern void CloseDisplay();
extern void SetMono();
extern void ClearWindow();
extern void DrawPoly();
extern int WinHOrig, WinVOrig;
extern int XOR, WRITE;
extern short DitherMask;
#define CntrX(XVAL) ((XVAL) - WinHOrig)
#define CntrY(YVAL) (WinVOrig - (YVAL)) /* fudge for the mouse */
#define UCntrX(XVAL) ((XVAL) + WinHOrig)
#define UCntrY(YVAL) (WinVOrig - (YVAL))
\Rogue\Monster\
else
echo "will not over write ./scrnio.h"
fi
if `test ! -s ./scrnio.ih`
then
echo "writing ./scrnio.ih"
cat > ./scrnio.ih << '\Rogue\Monster\'
/* main program */
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
extern struct Screen *SurfScrn;
extern struct Window *SurfWin;
extern struct Window *CntrlWin;
extern struct Window *GadWin;
extern long BackColor;
/*
* bit masks for waiting for signals
*/
extern short CntrlSigBit, SurfSigBit, GadSigBit;
extern long SignalMask;
extern struct RastPort *rp;
extern struct ViewPort *vp;
extern int WinFgCol;
extern int ColorMax;
extern int NumColors;
extern UWORD GrayPat[9][4];
#define DefBkPlane 0
\Rogue\Monster\
else
echo "will not over write ./scrnio.ih"
fi
if `test ! -s ./scrnops.c`
then
echo "writing ./scrnops.c"
cat > ./scrnops.c << '\Rogue\Monster\'
#include "scrnio.ih"
#ifdef MANX
#include <functions.h>
#endif
#include "scrndef.h"
#include "scrnio.h"
#include "gadgetdef.h"
#include "menudef.h"
#include "bezpt.h"
#include "revolve.h"
#include "control.h"
#include "poly.h"
long BackColor = DefBkPlane;
short DitherMask = 7;
void SetMono( maxrval, maxgval, maxbval )
short maxrval,
maxgval,
maxbval;
{
long i;
short range;
long rval, gval, bval;
range = (NumColors -1) & 0x1f; /* max 32 colours */
for( i = 0; i <= range; i++ ) {
rval = (maxrval * i )/range;
gval = (maxgval * i )/range;
bval = (maxbval * i )/range;
SetRGB4( &(SurfScrn->ViewPort), i, rval, gval, bval );
}
}
void SetRainbow()
{
long i;
short range;
long rval, gval, bval;
range = NumColors>> 1;
/*
* can't do a rainbow with only 2 colors
*/
if( range < 2) {
return;
}
for( i = 0; i < range; i++ ) {
long diff;
diff = (0xf * i )/(range-1);
rval = 0xf - diff;
bval = diff;
gval = 0xf;
SetRGB4( &(SurfScrn->ViewPort), i, rval, gval, bval);
}
for( i = 0; i < range; i++ ) {
long diff;
diff = (0xf * i )/(range-1);
rval = diff;
bval = 0xf;
gval = 0xf - diff;
SetRGB4( &(SurfScrn->ViewPort), i+range, rval, gval, bval);
}
SetRGB4( &(SurfScrn->ViewPort), 0L, 0L, 0L, 0L);
}
/*
* set colours for hourglass pointer
*/
SetHourGlassCol()
{
SetRGB4( &(SurfScrn->ViewPort),17L, 6L, 2L, 3L );
SetRGB4( &(SurfScrn->ViewPort),18L, 0L, 0L, 0L );
SetRGB4( &(SurfScrn->ViewPort),19L, 9L, 7L, 6L );
}
void ClrWindow(drawaxis)
bool drawaxis;
{
long BkColAdj; /* background color adjusted for number of bit planes */
BkColAdj = (BackColor * NumColors) / 32;
SetRast(rp, BackColor); /* clear the window to colour 0 */
SetAPen(rp, WinFgCol );
/*
* Draw axis on screen
*/
if( drawaxis) {
Move( rp, 0, WinVOrig); /* x axis */
Draw( rp, (long)SurfWinDef.Width, (long)WinVOrig );
Move( rp, WinHOrig, 0); /* y axis */
Draw( rp, (long)WinHOrig, (long)SurfWinDef.Height );
}
}
void DrawLine( x1, y1, x2, y2, mode )
int x1, y1, x2, y2;
int mode;
{
SetDrMd( rp, mode );
Move( rp, (long)UCntrX(x1), (long)UCntrY(y1));
Draw(rp, (long)UCntrX(x2), (long)UCntrY(y2) );
}
void PaintPoint(x,y,forecolor)
short x, y;
float forecolor;
{
long shade;
shade = forecolor * (NumColors-1);
if( shade >= NumColors) {
shade = NumColors-1;
}
else if ( shade < 0 ) {
shade = 0;
}
SetAPen( rp, shade );
WritePixel( rp, (long)UCntrX(x), (long)UCntrY(y));
}
void DrawPnt( x, y, op )
int x, y, op;
{
x = UCntrX(x);
y = UCntrY(y);
SetDrMd(rp, op );
RectFill( rp, (long)x, (long)y, (long)x, (long)y);
}
void DrawSqr(x, y, op )
int x, y, op;
{
x = UCntrX(x);
y = UCntrY(y);
SetDrMd(rp, op );
RectFill( rp, x - 2L, y -2L, x+ 2L, y+2L );
}
void DrawRhomShade( poly)
Rhomboid *poly;
{
int i;
int shade;
long backcolor, forecolor;
shade = (int)((poly->intensity) * ColorMax);
if( shade > ColorMax) {
shade = ColorMax;
}
backcolor = shade >> 3;
forecolor = backcolor +1;
if( forecolor >= NumColors ) {
forecolor = backcolor;
}
SetDrMd( rp, JAM2);
SetAPen( rp, forecolor );
SetBPen( rp, backcolor );
SetAfPt( rp, GrayPat[ shade & DitherMask ], 2);
AreaMove( rp, UCntrX(poly->pt[0].x), UCntrY(poly->pt[0].y));
for( i = 1; i < 4; i++ ) {
AreaDraw( rp, UCntrX(poly->pt[i].x), UCntrY(poly->pt[i].y) );
}
AreaEnd(rp);
SetAfPt( rp, GrayPat[8], 2); /* reset back to solid */
}
void DrawRhomFrame( inlist )
ScrnPair inlist[];
{
int i;
SetDrMd( rp, JAM1);
SetAPen( rp, 0L );
SetOPen( rp, WinFgCol );
AreaMove( rp, UCntrX(inlist[0].x), UCntrY(inlist[0].y));
for( i = 1; i < 4; i++ ) {
AreaDraw( rp, UCntrX(inlist[i].x), UCntrY(inlist[i].y) );
}
AreaEnd(rp);
BNDRYOFF( rp ); /* turn off outlining */
}
SwitchBox()
{
struct IntuiMessage mycopy,
*orig;
RefreshGadgets(SurfWinDef.FirstGadget, SurfWin, NULL );
while(1) {
long wakeupmask;
wakeupmask = Wait( SignalMask );
/*
* for now, we ignore the wakeupmask,
* just read messages from each. if I notice a performance problem,
* I'll fix it then
*/
/*
* handle messages for the control window
*/
while( orig =(struct IntuiMessage *) GetMsg( CntrlWin->UserPort ) ) {
mycopy = *orig;
ReplyMsg( orig );
switch( mycopy.Class ) {
case MENUPICK:
MenuHandler( mycopy.Code );
break;
case GADGETUP:
GadgetHandler( (struct Gadget*)mycopy.IAddress );
break;
case CLOSEWINDOW:
return;
default:
break;
}
}
/*
* handle the button window
*/
while( orig =(struct IntuiMessage *) GetMsg( GadWin->UserPort ) ) {
mycopy = *orig;
ReplyMsg( orig );
switch( mycopy.Class ) {
case GADGETUP:
GadgetHandler( (struct Gadget*)mycopy.IAddress );
RefreshGadgets(SurfWinDef.FirstGadget, SurfWin, NULL );
break;
default:
break;
}
}
/*
* handle messages for the other window
*/
while( orig =(struct IntuiMessage *) GetMsg( SurfWin->UserPort ) ) {
mycopy = *orig;
ReplyMsg( orig );
switch( mycopy.Class ) {
case MOUSEBUTTONS:
HandleMButtons(&mycopy);
break;
case INTUITICKS:
HandleTicks(&mycopy);
break;
case MOUSEMOVE:
break;
default:
break;
}
}
}
}
/*
* display error messages inside a requestor
*/
OutErr(errstr)
char *errstr;
{
static struct IntuiText errtext =
{ -1, -1, JAM1, 10, 10, NULL, NULL, NULL };
static struct IntuiText negtext =
{ -1, -1, JAM1, 80, 20, NULL,(UBYTE *)"Onwards", NULL };
errtext.IText = (UBYTE *)errstr;
WBenchToFront();
AutoRequest(CntrlWin, &errtext, NULL, &negtext, NULL, NULL,
8*strlen(errstr)+ 40, 60 );
WindowToFront( CntrlWin );
}
\Rogue\Monster\
else
echo "will not over write ./scrnops.c"
fi
if `test ! -s ./surf.lnk`
then
echo "writing ./surf.lnk"
cat > ./surf.lnk << '\Rogue\Monster\'
ROOT lib:c.o
scrnio.o
scrnops.o
scrndef.o
main.o
gadgetdef.o
menudef.o
graypat.o
mouse.o
gadgetuse.o
bezpt.o
revolve.o
control.o
poly.o
fasttrig.o
readilbm.o
writeilbm.o
packer.o
mapstuff.o
mapcalc.o
getfilenames.o
mapimgpix.o
LIBRARY LIB:lcmffp.lib
Lib:lc.lib
LIB:amiga.lib
TO Surf
verbose
nodebug
\Rogue\Monster\
else
echo "will not over write ./surf.lnk"
fi
if `test ! -s ./writeilbm.c`
then
echo "writing ./writeilbm.c"
cat > ./writeilbm.c << '\Rogue\Monster\'
#include <stdio.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#ifdef MANX
#include <functions.h>
#endif
#include "mytypes.h"
extern int PackRow();
/*
* following definitions cut from ilbm.h file
*/
typedef UBYTE Masking; /* Choice of masking technique.*/
#define mskNone 0
#define mskHasMask 1
#define mskHasTransparentColor 2
#define mskLasso 3
typedef UBYTE Compression; /* Choice of compression algorithm applied to
* each row of the source and mask planes. "cmpByteRun1" is the byte run
* encoding generated by Mac's PackBits. See Packer.h . */
#define cmpNone 0
#define cmpByteRun1 1
/* Aspect ratios: The proper fraction xAspect/yAspect represents the pixel
* aspect ratio pixel_width/pixel_height.
*
* For the 4 Amiga display modes:
* 320 x 200: 10/11 (these pixels are taller than they are wide)
* 320 x 400: 20/11
* 640 x 200: 5/11
* 640 x 400: 10/11 */
#define x320x200Aspect 10
#define y320x200Aspect 11
#define x320x400Aspect 20
#define y320x400Aspect 11
#define x640x200Aspect 5
#define y640x200Aspect 11
#define x640x400Aspect 10
#define y640x400Aspect 11
/* A BitMapHeader is stored in a BMHD chunk. */
typedef struct {
UWORD w, h; /* raster width & height in pixels */
WORD x, y; /* position for this image */
UBYTE nPlanes; /* # source bitplanes */
Masking masking; /* masking technique */
Compression compression; /* compression algoithm */
UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
UWORD transparentColor; /* transparent "color number" */
UBYTE xAspect, yAspect; /* aspect ratio, a rational number x/y */
WORD pageWidth, pageHeight; /* source "page" size in pixels */
} BitMapHeader;
/* RowBytes computes the number of bytes in a row, from the width in pixels.*/
#define RowBytes(w) (((w) + 15) >> 4 << 1)
#define IDSIZE 4
WriteIlbm( filename, win, scrn,packflag )
char *filename;
struct NewWindow *win;
struct NewScreen *scrn;
bool packflag;
{
FILE *ofile;
long formpos; /* position of length following 'FORM' */
long formsize;
struct ViewPort *vp;
ofile = fopen(filename,"w");
if( !ofile ) {
return;
}
fwrite("FORM", IDSIZE, 1, ofile);
formpos = ftell( ofile );
fwrite( &formsize, sizeof(formsize), 1, ofile); /* will be rewritten */
fwrite( "ILBMBMHD", IDSIZE*2, 1, ofile );
{
BitMapHeader bmhdr;
long bmhdrsize;
static UBYTE xaspect[2][2]= { { x320x200Aspect, x320x400Aspect },
{ x640x200Aspect, x640x400Aspect }};
static UBYTE yaspect[2][2]= { { y320x200Aspect, y320x400Aspect },
{ y640x200Aspect, y640x400Aspect }};
int wx, wy;
bmhdrsize = 20;
fwrite( &bmhdrsize, sizeof(bmhdrsize), 1, ofile);
bmhdr.x = bmhdr.y = 0;
bmhdr.w = win->Width;
bmhdr.h = win->Height;
bmhdr.nPlanes = scrn->Depth;
bmhdr.masking = mskNone;
bmhdr.compression = packflag ?cmpByteRun1: cmpNone;
bmhdr.pad1 = 0;
wx = (scrn->Width == 320)? 0: 1;
wy = (scrn->Height == 200)? 0: 1;
bmhdr.xAspect = xaspect[wx][wy];
bmhdr.yAspect = yaspect[wx][wy];
bmhdr.pageHeight = win->Height;
bmhdr.pageWidth = scrn->Width;
bmhdr.transparentColor = 0;
fwrite(&bmhdr, bmhdrsize, 1, ofile );
}
fwrite("CMAP",IDSIZE, 1, ofile);
vp = &win->Screen->ViewPort;
{
long cmapsize;
long i;
UWORD value;
UBYTE col[3];
int numentries;
numentries = (1<< scrn->Depth );
cmapsize = numentries*3;
fwrite( &cmapsize, sizeof(cmapsize), 1,ofile);
for( i = 0; i < numentries; i++ ) {
value = GetRGB4(vp->ColorMap, i);
col[2] = (value & 0xf) << 4; /* blue */
col[1] = value & 0xf0; /* green */
col[0] = (value & 0xf00) >> 4; /* red */
fwrite(col, 3, 1, ofile);
}
}
fwrite("CAMG", IDSIZE, 1, ofile);
{
long viewmode;
long viewmodesize;
viewmodesize = sizeof(viewmode);
viewmode = scrn->ViewModes;
fwrite(&viewmodesize, sizeof(viewmodesize), 1, ofile);
fwrite(&viewmode, sizeof(viewmode), 1, ofile );
}
fwrite("BODY", IDSIZE,1, ofile);
{
struct BitMap *bm;
long bodypos,
bodysize;
UBYTE *bmd[16]; /* assume as many as 16 bit planes :-) */
int row;
int plane;
int rowlength; /* in bytes */
char outbuff[200]; /* largest enough for a row 1600 bits wide */
bodypos = ftell(ofile);
fwrite( &bodysize, sizeof(bodysize), 1, ofile);
bm = vp->RasInfo->BitMap;
rowlength = RowBytes(scrn->Width);
for( plane = 0; plane < scrn->Depth; plane++ ) {
bmd[plane] = bm->Planes[plane] + rowlength * win->TopEdge;
}
/*
* write actual bitplanes
*/
for( row = 0; row < win->Height; row++ ) {
for( plane = 0; plane < scrn->Depth; plane++ ) {
if( packflag ) {
int packedsize;
packedsize = PackRow(bmd[plane],outbuff, rowlength );
fwrite(outbuff, packedsize, 1, ofile);
}
else {
fwrite(bmd[plane], rowlength, 1, ofile );
}
bmd[plane] += rowlength;
}
}
bodysize = ftell(ofile) -( bodypos + 4);
/*
* fill out body to make even
*/
if( bodysize & 1 ) {
fputc(0,ofile);
bodysize++;
}
formsize = ftell(ofile) -( formpos + 4);
fseek( ofile, bodypos, 0L );
fwrite( &bodysize, sizeof(bodysize), 1, ofile);
}
fseek( ofile, formpos, 0L );
fwrite( &formsize, sizeof(formsize), 1, ofile);
fclose(ofile);
}
\Rogue\Monster\
else
echo "will not over write ./writeilbm.c"
fi
echo "Finished archive 1 of 3"
# if you want to concatenate archives, remove anything after this line
exit
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
"I can't tell the difference between ABC News and Hill Street Blues" -Bono